package org.jtoc.maven;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.jtoc.convertor.ProjectConvertor;

/**
 * Usage : mvn com.google.code.jtoc:maven-jtoc-plugin:0.1:convertproject
 * -Djtoc.outputdir="expectedDir"
 * 
 * @goal convertproject
 * @phase generate-sources
 */
public class JtocConvertor extends AbstractMojo {

	/**
	 * the location of the project to be converted
	 * 
	 * @parameter default-value="."
	 */
	private File inputDir;

	/**
	 * the desired location where the converted files to be located
	 * 
	 * @parameter expression="${jtoc.outputdir}"
	 */
	private File outputDir;

	/**
	 * true if we would like to rewrite all files, otherwise the Converter would
	 * only rewrite the files that are out-dated.
	 * 
	 * @parameter expression="${jtoc.force}"
	 */
	private boolean forceRewrite;

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.apache.maven.plugin.AbstractMojo#execute()
	 */
	public void execute() throws MojoExecutionException {
		try {
			getLog().info("Begin Jtoc Conversion with Maven");
			getLog().info(
					"The Input Directory is " + inputDir.getAbsolutePath());

			if (outputDir == null)
				throw new Exception("the outputDir must be specified");

			getLog().info(
					"The Output Directory is " + outputDir.getAbsolutePath());

			if (outputDir.getAbsolutePath().equals(inputDir.getAbsolutePath()))
				throw new Exception(
						"The outputDir and inputDir must not be the same");

			getLog().info(
					"Should Force Rewriting " + Boolean.toString(forceRewrite));

			ProjectConvertor.convertProject(inputDir, outputDir, forceRewrite);
			this.processMavenConfigFile(new File(outputDir, "pom.xml"));

			getLog().info("Jtoc Conversion Finished Successfully");
		} catch (Exception e) {
			throw new MojoExecutionException(
					"Exception catched when processing Jtoc convertion", e);
		}
	}

	/**
	 * modify the output project's pom.xml to change its artifactId in order to
	 * avoid interfering the product build.
	 * 
	 * @throws Exception
	 * 
	 */
	void processMavenConfigFile(File pom) throws Exception {
		getLog().debug("Process Maven Config File pom.xml");

		if (!pom.exists()) {
			getLog().info("The generated project don't have pom.xml");
			return;
		}

		SAXReader reader = new SAXReader();
		Document doc = reader.read(pom);
		Element root = doc.getRootElement();

		// modify its artifactId in order to avoid interfering the product build
		Element artifactId = root.element("artifactId");
		if (artifactId == null) {
			getLog().info(
					"The specified pom.xml don't have the artifactId element");
			return;
		}
		artifactId.setText(artifactId.getText() + "_jtoc");

		// remove the jtoc build plug-in of the pom.xml
		Element plugins = root.element("build").element("plugins");

		if (plugins == null) {
			getLog().info("The specified pom.xml don't have 'build/plugins'");
			return;
		}

		for (Iterator<Element> iter = plugins.elementIterator("plugin"); iter
				.hasNext();) {
			Element element = iter.next();

			if (element.elementText("artifactId").equals("maven-jtoc-plugin")
					&& element.elementText("groupId").equals("com.google.code.jtoc")) {
				plugins.remove(element);
				break;
			}
		}

		XMLWriter output = new XMLWriter(new FileWriter(pom));
		output.write(doc);
		output.close();
	}
}
